﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Newtonsoft.Json;
using Polly.Caching;
using SportsPlatform.Base;
using SportsPlatform.Consts;
using SportsPlatform.Dto.PermissionManagement.UserInfo;
using SportsPlatform.Global;
using SportsPlatform.Helpers;
using System;

namespace SportsPlatform.Filters
{
    /// <summary>
    /// 权限控制过滤器
    /// </summary>
    [AttributeUsage(AttributeTargets.Class)]
    public class ActionAuthorization : Attribute, IAuthorizationFilter
    {
        #region 系统前置鉴权

        /// <summary>
        /// 系统前置鉴权
        /// </summary>
        /// <param name="context">AuthorizationFilterContext</param>
        public void OnAuthorization(AuthorizationFilterContext context)
        {
            var actionResult = new BaseResultDto();
            //处理匿名方法
            foreach (var item in context.ActionDescriptor.EndpointMetadata)
            {
                if (item.GetType().Name.Equals(typeof(AllowAnonymousAttribute).Name))
                {
                    return;
                }
            }
            //处理白名单
            var whiteList = UldAdminGlobalContext.SystemConfig.WhiteList;
            if (!String.IsNullOrEmpty(whiteList))
            {
                var array = whiteList.Split(',');
                var url = context.HttpContext.Request.Path.Value;
                foreach (var item in array)
                {
                    if (url.EndsWith(item))
                    {
                        return;
                    }
                }
            }
            var Authorization = context.HttpContext.Request.Headers["Authorization"];
            if (Authorization.Count >= 1)
            {
                //Jwt验证
                if (UldAdminGlobalContext.SystemConfig.CheckJwtToken)
                {
                    if (!context.HttpContext.Request.Headers.ContainsKey("Authorization"))
                    {
                        actionResult.Code = HttpResultCode.Token_Invalid;
                        actionResult.IsSuccess = true;
                        context.HttpContext.Response.StatusCode = 501;

                        actionResult.Message = new String("未经授权的 JWT 令牌");
                        context.Result = new ContentResult
                        {
                            Content = JsonConvert.SerializeObject(actionResult),
                            ContentType = "application/json;charset=utf-8",
                            StatusCode = 501
                        };
                        return;
                    }
                }

                //Token验证
                if (UldAdminGlobalContext.SystemConfig.CheckToken)
                {
                    if (!context.HttpContext.Request.Headers.ContainsKey("token"))
                    {
                        actionResult.Code = HttpResultCode.Token_Invalid;
                        actionResult.Message = new String("令牌是必要的");
                        context.HttpContext.Response.StatusCode = 501;

                        actionResult.IsSuccess = true;
                        //处理非法请求
                        context.Result = new ContentResult
                        {
                            Content = JsonConvert.SerializeObject(actionResult),
                            ContentType = "application/json;charset=utf-8",
                            StatusCode = 501,
                        };
                        return;
                    }
                    else
                    {
                        #region 用户token续时操作

                        //获取用户token
                        var token = context.HttpContext.GetToken();
                        //获取用户
                        var user = UldRedisContext.Get<GetLoginUserInfoDto>(token);
                        //用户token合法
                        if (user != null)
                        {
                            String salt = context.HttpContext.GetTokenSalt();
                            Guid id = Guid.Parse(salt);

                            if (id == Guid.Empty)
                            {
                                actionResult.Code = HttpResultCode.Token_Invalid;
                                actionResult.IsSuccess = true;
                                actionResult.Message = new String("非法盐，访问被拒绝");
                                context.HttpContext.Response.StatusCode = 501;

                                //处理非法请求
                                context.Result = new ContentResult
                                {
                                    Content = JsonConvert.SerializeObject(actionResult),
                                    ContentType = "application/json;charset=utf-8",
                                    StatusCode = 501,
                                };
                                return;
                            }
                        }
                        else
                        {
                            actionResult.Code = HttpResultCode.Token_Invalid;
                            actionResult.IsSuccess = true;
                            actionResult.Message = new String("无效的用户令牌");
                            context.HttpContext.Response.StatusCode = 501;
                            //处理非法请求
                            context.Result = new ContentResult
                            {
                                Content = JsonConvert.SerializeObject(actionResult),
                                ContentType = "application/json;charset=utf-8",
                                StatusCode = 501,
                            };
                            return;
                        }

                        #endregion
                    }
                }

                //其他头部验证
                var headerConfig = UldAdminGlobalContext.SystemConfig.HeaderConfig;
                if (!String.IsNullOrEmpty(headerConfig))
                {
                    var array = headerConfig.Split(',');
                    foreach (var item in array)
                    {
                        if (!context.HttpContext.Request.Headers.ContainsKey(item))
                        {
                            context.Result = new ContentResult
                            {
                                Content = item.ToLower() + " is necessary",
                                ContentType = "application/json;charset=utf-8",
                                StatusCode = 501
                            };
                            return;
                        }
                    }
                }
            }
            else
            {
                actionResult.Code = HttpResultCode.Fail;
                actionResult.IsSuccess = false;
                actionResult.Message = "未传入Token,请重新登陆";
                context.Result = new ContentResult
                {
                    Content = JsonConvert.SerializeObject(actionResult),
                    ContentType = "application/json;charset=utf-8",
                    StatusCode = 412
                };
                return;
            }


        }
        #endregion
    }
}
